/blog/

Moving the blog to to a text file based backend

created: 2020-12-26T15:47:01Z
modified: 2020-12-26T15:47:01Z

So it occured to me that the amount of work it would take to make a traditional database powered CMS in Rust from scratch was more than I wanted to put into it. So I came up with an idea to rebuild it as a CMS based on plain textfiles, Markdown or HTML. Then as I started putting it into code it became obvious that this was a good idea. And I learned some new tricks in Rust so I thought I’d share.

For instance to get a directory listing in Rust is really easy:

let paths = fs::read_dir("/some/file/path/to/dir/").unwrap()

https://doc.rust-lang.org/std/fs/fn.read_dir.html

Which is simple, but comes with a catch. The directory contents are returned as path objects which display as OsStrings instead of normal Strings in an iterator. Which for a particular use case I needed, wasn’t working. But the solution was at hand in the standard library with to_string_lossy().

for item in paths {
    let this_path = &item.unwrap().path();
	...
         title: String::from(this_path.file_stem().unwrap().to_string_lossy()),

Also I needed the file creation time which was available in fs::metadata()but it also needed some massaging into something I could work with. So with the metadata object from .created():

actual_time = _time.duration_since(UNIX_EPOCH).unwrap().as_secs() as i64

Maybe not the safest way to do it, but the .as_secs() returns a u64 value and I needed an i64 for Chrono NaiveDateTime::from_timestamp(actual_time, 0).

So basically I now have a struct filled with the 3 minimum pieces of data I need to make a blog workflow.

let new_content = MDContent {
                created: read_file_creation_time(&this_path),
                title: String::from(this_path.file_stem().unwrap().to_string_lossy()),
                body: read_markdown_from_path(&this_path),
            };

Throw the structs in a Vec and then get them minimally sorted via the "created" key of the struct with the Vec built in contents.sort_unstable_by_key(|x| x.created);.

So this took less than a hundred lines of code and the original Diesel/Postgres code I wrote to do the same is about 200 lines. It doesn’t perceptually seem to be any faster or slower than the DB based code. It’s in a Git repository so I have versioning and easy backups. I can edit the posts in Obsidian. Seems like a bunch of wins, so maybe I’m onto something here?

  • Creative Commons License
  • Author: Gatewaynode